///PHILOTES Source Code.  (C)2012 PhiloLabs
#pragma once

#include "ExtrasPrerequisites.h "

#include "OverlayElement.h"
#include "Font.h"

namespace Extras
{
	
    class _PhiloExtrasExport TextAreaOverlayElement : public OverlayElement
    {
    public:
        enum Alignment
        {
            Left,
            Right,
            Center
        };

    public:
        
        TextAreaOverlayElement(const Ogre::String& name);
        virtual ~TextAreaOverlayElement();

        virtual void initialise(void);
		virtual void setCaption(const DisplayString& text);

        void setCharHeight( Real height );
        Real getCharHeight() const;

        void setSpaceWidth( Real width );
        Real getSpaceWidth() const;

        void setFontName( const Ogre::String& font );
        const Ogre::String& getFontName() const;

        
        virtual const Ogre::String& getTypeName(void) const;
        
		const MaterialPtr& getMaterial(void) const;
        
        void getRenderOperation(RenderOperation& op);
        
        void setMaterialName(const Ogre::String& matName);

        
        void setColour(const ColourValue& col);

        
        const ColourValue& getColour(void) const;
        
        void setColourBottom(const ColourValue& col);
        
        const ColourValue& getColourBottom(void) const;
        
        void setColourTop(const ColourValue& col);
        
        const ColourValue& getColourTop(void) const;

        inline void setAlignment( Alignment a )
        {
            mAlignment = a;
			mGeomPositionsOutOfDate = true;
        }
        inline Alignment getAlignment() const
        {
            return mAlignment;
        }

        
        void setMetricsMode(GuiMetricsMode gmm);

        
        void _update(void);

        //-----------------------------------------------------------------------------------------
        
        class CmdCaption : public ParamCommand
        {
        public:
            Ogre::String doGet( const void* target ) const;
            void doSet( void* target, const Ogre::String& val );
        };
        //-----------------------------------------------------------------------------------------
        
        class CmdCharHeight : public ParamCommand
        {
        public:
            Ogre::String doGet( const void* target ) const;
            void doSet( void* target, const Ogre::String& val );
        };
        //-----------------------------------------------------------------------------------------
        
        class CmdSpaceWidth : public ParamCommand
        {
        public:
            Ogre::String doGet( const void* target ) const;
            void doSet( void* target, const Ogre::String& val );
        };
        //-----------------------------------------------------------------------------------------
        
        class CmdFontName : public ParamCommand
        {
        public:
            Ogre::String doGet( const void* target ) const;
            void doSet( void* target, const Ogre::String& val );
        };
        //-----------------------------------------------------------------------------------------
        
        class CmdColourTop : public ParamCommand
        {
        public:
            Ogre::String doGet( const void* target ) const;
            void doSet( void* target, const Ogre::String& val );
        };
        //-----------------------------------------------------------------------------------------
        
        class CmdColourBottom : public ParamCommand
        {
        public:
            Ogre::String doGet( const void* target ) const;
            void doSet( void* target, const Ogre::String& val );
        };
        //-----------------------------------------------------------------------------------------
        
        class CmdColour : public ParamCommand
        {
        public:
            Ogre::String doGet( const void* target ) const;
            void doSet( void* target, const Ogre::String& val );
        };
        //-----------------------------------------------------------------------------------------
        
        class CmdAlignment : public ParamCommand
        {
        public:
            Ogre::String doGet( const void* target ) const;
            void doSet( void* target, const Ogre::String& val );
        };

    protected:
        /// The text alignment
        Alignment mAlignment;

        /// Flag indicating if this panel should be visual or just group things
        bool mTransparent;

        /// Render operation
        RenderOperation mRenderOp;

        /// Method for setting up base parameters for this class
        void addBaseParameters(void);

        static Ogre::String msTypeName;

        // Command objects
        static CmdCharHeight msCmdCharHeight;
        static CmdSpaceWidth msCmdSpaceWidth;
        static CmdFontName msCmdFontName;
        static CmdColour msCmdColour;
        static CmdColourTop msCmdColourTop;
        static CmdColourBottom msCmdColourBottom;
        static CmdAlignment msCmdAlignment;


        FontPtr mFont;
        Real mCharHeight;
        ushort mPixelCharHeight;
        Real mSpaceWidth;
        ushort mPixelSpaceWidth;
        size_t mAllocSize;
		Real mViewportAspectCoef;

        /// Colours to use for the vertices
        ColourValue mColourBottom;
        ColourValue mColourTop;
        bool mColoursChanged;


        /// Internal method to allocate memory, only reallocates when necessary
        void checkMemoryAllocation( size_t numChars );
        /// Inherited function
        virtual void updatePositionGeometry();
		/// Inherited function
		virtual void updateTextureGeometry();
        /// Updates vertex colours
        virtual void updateColours(void);
    };
	
	
}


